package cn.stylefeng.guns.utils;

import cn.stylefeng.guns.modular.bms.model.params.CityParam;
import cn.stylefeng.guns.modular.bms.service.CityService;
import org.apache.commons.lang.StringEscapeUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class AsyncCitysUtil {

    private CityService cityService;

    public void startAsync(CityService cityService){
        this.cityService=cityService;
        Runnable runnable=new AsyncThread();
        Thread thread=new Thread(runnable);
        thread.start();
    }

    public class AsyncThread implements Runnable{

        @Override
        public void run() {
            try {
                start();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    private static Map<Integer, String> cssMap = new HashMap<>();
    private static BufferedWriter bufferedWriter = null;

    static {
        cssMap.put(1, "provincetr");// 省
        cssMap.put(2, "citytr");// 市
        cssMap.put(3, "countytr");// 县/区
        cssMap.put(4, "towntr");// 镇
        cssMap.put(5, "villagetr");// 村
    }

    public static void main(String[] args) throws Exception {
        String name="&#xfffd;&#xfffd;";
//        String name="&#x4e2d;&#x56fd;";
        name=StringEscapeUtils.unescapeHtml(name);
        System.out.println(name);
    }

    private void start() throws Exception{
        int level = 1;
        initFile();
        // 获取全国各个省级信息
        Document connect = connect("http://www.stats.gov.cn/tjsj/tjbz/tjyqhdmhcxhfdm/2020/");
        Elements rowProvince = connect.select("tr." + cssMap.get(level));
        for (Element provinceElement : rowProvince)// 遍历每一行的省份城市
        {
            Elements select = provinceElement.select("a");
//            System.out.println("--------------select-----------------："+provinceElement);
            for (Element province : select)// 每一个省份
            {
//                System.out.println("-------------province-------------------："+province);
                printInfoProvice(province, level);
                Elements elements=new Elements();
                elements.add(new Element("a").text("0"));
                elements.add(province);
//                System.out.println("-------------elements-------------------："+elements);
                parseNextLevel(elements, level + 1);
            }
        }
        closeStream();
    }

    private static void initFile() {
        try {
            bufferedWriter = new BufferedWriter(new FileWriter(new File("d:\\ShowAdress.txt"), true));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private static void closeStream() {
        if (bufferedWriter != null) {
            try {
                bufferedWriter.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bufferedWriter = null;
        }
    }

    private void parseNextLevel(Elements parentElement, int level) throws IOException {
        if(level>3){
            return;
        }
        try {
            Thread.sleep(100);//睡眠一下，否则可能出现各种错误状态码
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Document doc = connect(parentElement.last().attr("abs:href"));
        if (doc != null) {
            Elements newsHeadlines = doc.select("tr." + cssMap.get(level));//
            // 获取表格的一行数据
            for (Element element : newsHeadlines) {
                printInfo(parentElement, element, level);
//                System.out.println("-------------element-------------------："+element);
                Elements select = element.select("a");// 在递归调用的时候，这里是判断是否是村一级的数据，村一级的数据没有a标签
                if (select.size() != 0) {
                    parseNextLevel(select, level + 1);
                }
            }
        }
    }

    /**
     * 写一行数据到数据文件中去
     *
     * @param element 爬取到的数据元素
     *                *  @param level 城市级别
     */
    private void printInfo(Elements parentElement, Element element, int level) {
        try {
            String reg = "[^\u4e00-\u9fa5]";
//            System.out.println("level："+level);
//            System.out.println("parentElement："+parentElement);
//            System.out.println("parentElement："+parentElement.first().text());
//            System.out.println("element："+element);
            String name=element.select("td").last().text();
            if (name.startsWith("&#x")){
                name=StringEscapeUtils.unescapeHtml(name);
            }
//            String py=PinYinHelper.getSpells(name);
//            Character pyszm=PinYinHelper.getFirstLetter(name.charAt(0));
            String py=PinYinUtil.getLowerCase(name,true);
//            System.out.println(py);
            String pyszm=py.substring(0,1).toUpperCase();
//            System.out.println(pyszm);
            String code=element.select("td").first().text();

            String parentCode=parentElement.first().text();
            String parentName=parentElement.last().toString().replaceAll(reg, "");
            if (parentCode.equals("0")){
                //省份
                parentCode=code.substring(0,2)+"0000000000";
            }
//            if (level == 3) {
//                bufferedWriter.write(parentName+parentCode + "-[" + (level - 1) + "]" + name + code +py+pyszm  +",");
//            } else if (level == 4) {
//                bufferedWriter.write(parentName+parentCode + "-[" + (level - 1) + "]" + name + element.select("td").first().text() +py+pyszm+  ",");
//            } else if (level == 5) {
//                bufferedWriter.write(parentName+parentCode + "-[" + (level - 1) + "]" + name + element.select("td").first().text() +py+pyszm+  ",");
//            }
//            bufferedWriter.newLine();
//            bufferedWriter.flush();
            this.cityService.add(new CityParam().setCity(name).setCode(code).setPcode(parentCode).setPcity(parentName).setPy(py).setIndexLetter(pyszm).setLevel(level));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void printInfoProvice(Element element, int level) {
        try {
            String reg = "[^\u4e00-\u9fa5]";
//            bufferedWriter.write("province" + element.toString().replaceAll(reg, "") + ",");
//            bufferedWriter.newLine();
//            bufferedWriter.flush();
            String name=element.toString().replaceAll(reg, "");
            String py=PinYinUtil.getLowerCase(name,true);
            String pyszm=py.substring(0,1).toUpperCase();
            this.cityService.add(new CityParam().setCity(name).setLevel(1).setPy(py).setIndexLetter(pyszm));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Document connect(String url) {
        if (url == null || url.isEmpty()) {
            throw new IllegalArgumentException("The input url('" + url + "') is invalid!");
        }
        try {
            return Jsoup.connect(url).timeout(10 * 1000).get();
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

}
